<?php

namespace app\index\controller;

use app\common\controller\AuthBase;
use app\common\common\Constants;
use app\common\service\OssService;
use think\Validate;
use think\Config;

class Oss extends AuthBase {

    private $_ossService;

    public function _initialize() {
        parent::_initialize();
        //每次刷新config要重新实例化实例
        $this->_ossService = new OssService();
    }

    /**
     * 图片上传
     * @return type
     */
    public function fileUpload() {
        $params = $this->request->param();
        $rule = [
            "fileName" => 'require',
            "upType"   => 'require',
            "isRoot"   => 'require',
            'fileType' => 'require|number',
            'bucket'   => 'require'
        ];

        if (isset($params['upType']) && $params['upType'] == 'base64') {
            $rule['content'] = 'require';
        }

        $validate = new Validate($rule);
        if (!$validate->check($params)) {
            return $this->output([], $validate->getError());
        }
        $fileName = "{$params['fileName']}";
        $upType = "{$params['upType']}";
        $isRoot = "{$params['isRoot']}";
        $fileType = "{$params['fileType']}";
        Config::set('ALIYUN_OSS_BUCKET', "{$params['bucket']}");
        $this->_ossService = new OssService();

        if (!empty($fileName)) {
            $ext = pathinfo($fileName, PATHINFO_EXTENSION);
        }
        //base64上传方式
        if ($upType == 'base64') {
            $content = isset($params['content']) ? $params['content'] : '';
            $rule = "/^(data:\s*image\/(\w+);base64,)/";
            if (preg_match($rule, $content, $match)) {
                $content = preg_replace($rule, '', $content);
                if (!empty($fileName) && empty($ext)) {
                    $dataImages = [
                        'gif'    => 'gif',
                        'png'    => 'png',
                        'jpeg'   => 'jpg',
                        'jpg'    => 'jpg',
                        'x-icon' => 'ico',
                    ];
                    $ext = $dataImages[$match[2]];
                    $fileName = rtrim($fileName, '.') . '.' . $ext;
                }
            }
            $realContent = base64_decode($content);
        }
        //普通文件上传方式
        else {
            //$content = $this->IJ('content', false, '内容不能为空');
            $content = isset($_FILES["content"]) ? $_FILES["content"] : [];
            if (empty($content)) {
                return $this->output([], '请选择要上传的文件');
            }
            if (!empty($fileName) && empty($ext)) {
                $imgType = $content["type"];
                $imageTypes = [
                    'image/gif'  => 'gif',
                    'image/jng'  => 'png',
                    'image/jpeg' => 'jpg',
                ];
                if (!empty($imgType) && in_array($imgType, $imageTypes)) {
                    $ext = $imageTypes[$imgType];
                } else if (!empty($content["name"])) {
                    $ext = pathinfo($content["name"], PATHINFO_EXTENSION);
                }
                $fileName = rtrim($fileName, '.') . (!empty($ext) ? '.' . $ext : '');
            }
            $realContent = $content ? file_get_contents($content["tmp_name"]) : null;
        }
        //$fileType = $this->IJ('fileType', false, '文件类型不能为空');
        //文件类型判断
        if (!in_array($fileType, Constants::$fileType)) {
            return $this->jsonOutput('failure', "文件类型不正确");
        }
        //向阿里推送图片
        $type = array_flip(Constants::$fileType);
        if ($isRoot) {
            $fileSavePath = ltrim($fileName, '/');
        } else {
            $fileSavePath = $type[$fileType] . '/' . date("Ym") . '/' . $fileName;
        }


        //重试3次
        $times = 3;
        while ($times--){
           try{
                $result = $this->_ossService->fileUpload($fileSavePath,$realContent);
                if($result){
                    return $this->output(['url'=>$result,'bucket'=>"{$params['bucket']}"],'success');
                }else{
                    $this->output(['times'=>$times,'bucket'=>"{$params['bucket']}"],"fail");
                }    
            } catch (\Exception $ex){
                continue;
            }
        }
        
        return $this->output(['times'=>$times,'bucket'=>"{$params['bucket']}"],"上传失败");
    }

    /**
     * 下载文件
     */
    public function downFile(){
        $params = $this->input();
        $rule = [
            'filePath' => 'require',
            "bucket"=>'require'
        ];
        $validate = new Validate($rule);
        if(!$validate->check($params)){
            return $this->output([], $validate->getError());
        }
       
        $filePath = "{$params['filePath']}";
        Config::set('ALIYUN_OSS_BUCKET',"{$params['bucket']}");
        $this->_ossService = new OssService();
        
        
        $res = $this->_ossService->downFile($filePath);
        die($res);
    }

    

    /**
     * 图片删除
     * @return type
     */
    public function fileDelete() {

        $params = $this->input();
        $rule = [
            "filePath" => 'require',
            "bucket"   => 'require'
        ];

        $validate = new Validate($rule);
        if (!$validate->check($params)) {
            return $this->output([], $validate->getError());
        }

        $filePath = "{$params['filePath']}";
        Config::set('ALIYUN_OSS_BUCKET', "{$params['bucket']}");
        $this->_ossService = new OssService();

        //重试3次
        $times = 3;
        while ($times--) {
            try {
                $exist = $this->_ossService->fileExist($filePath);
                if (TRUE !== $exist) {
                    return $this->output([], "filePath is not exist");
                }

                $result = $this->_ossService->fileDelete($filePath);
                if ($result) {
                    return $this->output([], "del success");
                } else {
                    $this->output(['times' => $times], "del fail");
                }
            } catch (\Exception $ex) {
                continue;
            }
        }

        return $this->output(['times' => $times], "del fail");
    }

    /**
     * 图片信息
     * @return type
     */
    public function imageInfo() {

        $params = $this->input();
        $rule = [
            "imagePath" => 'require',
            'ossDomain' => 'require',
            'bucket'    => 'require',
        ];

        $validate = new Validate($rule);
        if (!$validate->check($params)) {
            return $this->output([], $validate->getError());
        }

        $imagePath = "{$params['imagePath']}";
        Config::set('ALIYUN_OSS_BUCKET', "{$params['bucket']}");
        $this->_ossService = new OssService();

        //重试3次
        $times = 3;
        while ($times--) {
            try {
                $exist = $this->_ossService->fileExist($imagePath);
                if (TRUE !== $exist) {
                    return $this->output([], "image is not exist");
                }
                $result = $this->_ossService->imageInfo($imagePath, "{$params['ossDomain']}");
                if ($result) {
                    return $this->output($result, 'success');
                } else {
                    $this->output(['times' => $times], "fail");
                }
            } catch (\Exception $ex) {
                continue;
            }
        }
        return $this->output(['times' => $times], "fail");
    }

    /**
     * 图片是否存在
     * @return type
     */
    public function fileExist() {

        $params = $this->input();
        $rule = [
            "filePath" => 'require',
            "bucket"   => 'require'
        ];

        $validate = new Validate($rule);
        if (!$validate->check($params)) {
            return $this->output([], $validate->getError());
        }

        $filePath = "{$params['filePath']}";
        Config::set('ALIYUN_OSS_BUCKET', "{$params['bucket']}");
        $this->_ossService = new OssService();

        //重试3次
        $times = 3;
        while ($times--) {
            try {
                $result = $this->_ossService->fileExist($filePath);
                if ($result) {
                    return $this->output([], 'success');
                } else {
                    $this->output(['times' => $times], "fail");
                }
            } catch (\Exception $ex) {
                continue;
            }
        }
        return $this->output(['times' => $times], "fail");
    }

    public function bucketList() {

        //重试3次
        $times = 3;
        while ($times--) {
            try {
                $bucketList = $this->_ossService->bucketList();
                return $this->output($bucketList, "success");
            } catch (\Exception $ex) {
                continue;
            }
        }
        return $this->output(['times' => $times], "fail");
    }

    /**
     * 获取带有签名的路径
     * @param type $bucket
     * @param type $object
     * @param typ w 宽度 h 高度--选填
     * @return type
     */
    public function getSignUrl() {
        $params = $this->input();
        $rule = [
            "object" => 'require',
            "bucket" => 'require'
        ];
        $validate = new Validate($rule);
        if (!$validate->check($params)) {
            return $this->output([], $validate->getError());
        }
        $OssService = new OssService();
        $url = $OssService->getSignUrl($params);
        return $this->output(['url' => $url]);
    }

}
